package com.gudogudo.battleworm.element {
	import flash.events.MouseEvent;	
	import flash.utils.getTimer;
	import flash.display.MovieClip;
	
	import Box2D.Dynamics.*;	
	import Box2D.Collision.Shapes.*;	
	import Box2D.Common.Math.b2Vec2;	
//	import Box2D.Dynamics.Joints.*;	
	import Box2D.Common.Math.b2XForm;
	import Box2D.Collision.b2AABB;	
	
	import com.red.battleworm.AppMain;
	import com.gudogudo.battleworm.contact.ContactConfig;	
	import com.gudogudo.battleworm.model.Box2DConfig;	
	
	/**
	 * @author zhangs
	 */
	public class Player extends AbstractElement {
		public static var LEFTSPEED : b2Vec2 = new b2Vec2(-3, 0);
		public static var RIGHTSPEED : b2Vec2 = new b2Vec2(3, 0);
		public static var WIDTH : Number = 8;
		public static var HEIGHT : Number = 20;
		private static var LARGESTDISTANCE : Number = Number.MAX_VALUE;

//		private var m_world:b2World;
		private var polygonDef:b2PolygonDef;
//		private var circleDef : b2CircleDef;
//		private var headDef:b2BodyDef;
		private var bodyDef:b2BodyDef;
		public var arrow_rotation : Number;
		public var scale : Number;
		public var isControl : Boolean;
		
		private var arrow : MovieClip;
		private var arrow_length : Number;
		private var checkTime_replay : Number;
		private var action_steps : Array;
		private var lastDistance : Number;
		
		public function Player(m_world:b2World, birth:Object) {
			super(m_world);
			
			polygonDef = new b2PolygonDef();
//			circleDef = new b2CircleDef();
//			headDef = new b2BodyDef();
			bodyDef = new b2BodyDef();
			var width : Number = Math.abs(birth.width * Math.cos(birth.rotation));
			var height : Number = Math.abs(birth.height * Math.sin(birth.rotation));
			var x0 : Number = birth.x - width / 2;
			var x1 : Number = birth.x + width / 2;
			var y0 : Number = birth.y - height / 2;
			var y1 : Number = birth.y + height / 2;

			initBody(x0+Math.random()*(x1-x0), y0+Math.random()*(y1-y0));
			
			auto = false;
			
			arrow = new MC_Arrow();
			arrow_length = arrow.width;
			AppMain.stage.addChild(arrow);
			
			arrow.visible = true;
			clearActions();
			setSpeed(NONESPEED);
		}
		
		private function initBody(px:Number, py:Number) : void {
//			headDef.position.Set(px/Box2DConfig.PHYSSCALE, (py-(WIDTH+HEIGHT)/2)/Box2DConfig.PHYSSCALE);
//			headDef.fixedRotation = true;
//			circleDef.radius = WIDTH/Box2DConfig.PHYSSCALE/2;
////			circleDef.density = 20.0;
//			circleDef.friction = 1;
//			var headBody:b2Body = m_world.CreateBody(headDef);
//			headBody.CreateShape(circleDef);
//			headBody.SetMassFromShapes();
			
			var sd:b2PolygonDef = new b2PolygonDef();
			sd.SetAsBox(WIDTH/Box2DConfig.PHYSSCALE/2, HEIGHT/Box2DConfig.PHYSSCALE/2);
			sd.density = 1;
//			sd.friction = 0;
			var filter : b2FilterData = new b2FilterData();
			filter.groupIndex = ContactConfig.groupIndex_Player;
			sd.filter = filter;
			bodyDef.position.Set(px /Box2DConfig.PHYSSCALE, py/Box2DConfig.PHYSSCALE);
			bodyDef.fixedRotation = true;
			body = m_world.CreateBody(bodyDef);
			body.CreateShape(sd);
			body.SetMassFromShapes();
//			var mass : b2MassData = new b2MassData();
//			mass.mass = 0.0000001;
//			body.SetMass(mass);
			body.SetLinearVelocity(new b2Vec2(1, 0));
			
//			var jd:b2RevoluteJointDef = new b2RevoluteJointDef();
//			jd.enableLimit = true;
//			
//			var anchor:b2Vec2 = new b2Vec2();
//			anchor.Set(px/Box2DConfig.PHYSSCALE, (py-HEIGHT/2)/Box2DConfig.PHYSSCALE);
//			jd.Initialize(headBody, body, anchor);
//			m_world.CreateJoint(jd);
		}

		override public function setSpeed(speed : b2Vec2) : void {
//			trace(speed);
			super.setSpeed(speed);
			
			if(isControl && speed==NONESPEED) {
				action_steps.push({speed:this.speed, position:this.getPosition()});
				trace('add:\t', this.speed, this.getPosition(), action_steps.length);
			}
			
			if (isControl && speed==NONESPEED) {
				arrow.visible = true;
			} else {
				arrow.visible = false;
			}
		}

		override public function run() : void {
			var action : Object;
			if(!isControl) {
				if(action_steps.length == 0) {
					clearActions();
					return;
				}
				action = action_steps[0];
				if(speed != action.speed) {
//					trace(speed, action.speed, action.position, action_steps.length);
					setSpeed(action.speed);
				}
			}
			var v : b2Vec2 = body.GetLinearVelocity();
			v.x = 0;
			body.SetLinearVelocity(v);
			arrow.x = this.getPosition().x*Box2DConfig.PHYSSCALE;
			arrow.y = this.getPosition().y*Box2DConfig.PHYSSCALE;
			super.run();
		}
		
		private function resetLastDistance() : void {
//			count_replay = 0;
			checkTime_replay = getTimer();
			lastDistance = LARGESTDISTANCE;
		}
		
		public function clearActions() : void {
			action_steps = [this.getPosition()];
			isControl = true;
			resetLastDistance();
		}

		public function playActions() : void {
			body.GetXForm().position = action_steps.shift();
			isControl = false;
		}
		
		public function getAABB() : b2AABB {
			var aabb:b2AABB = new b2AABB();
			aabb.lowerBound.Set(body.GetPosition().x-WIDTH/Box2DConfig.PHYSSCALE/2, body.GetPosition().y-HEIGHT/Box2DConfig.PHYSSCALE/2);
			aabb.upperBound.Set(body.GetPosition().x+WIDTH/Box2DConfig.PHYSSCALE/2, body.GetPosition().y+HEIGHT/Box2DConfig.PHYSSCALE/2);
			return aabb;
		}
		
		public function updateArrow(evt : MouseEvent) : void {
//			trace(evt.stageX, evt.stageY, body.px, body.py);
			
			/*
			if (!body.IsSleeping()) {
				body.PutToSleep();
			} else {
				body.WakeUp();
			}
			 * 
			 */
			var px : Number = this.getPosition().x*Box2DConfig.PHYSSCALE;
			var py : Number = this.getPosition().y*Box2DConfig.PHYSSCALE;
			var d : Number = Math.sqrt((evt.stageX-px)*(evt.stageX-px)+(evt.stageY-py)*(evt.stageY-py));
			scale = d / arrow_length;
			if (scale >= 1) {
				scale = 1;
			} else if (scale <= 0.3) {
				scale = 0.3;
			}
			if(evt.stageX == px) {
				if (evt.stageY >= py) {
					arrow_rotation = 90;
				} else {
					arrow_rotation = -90;
				}
			} else {
				var r : Number = Math.atan2((evt.stageX-px), (evt.stageY-py));
//				trace(r);
				arrow_rotation = 90-r/Math.PI*180;
			}
			arrow.scaleX = arrow.scaleY = scale;
			arrow.rotation = arrow_rotation;
		}
	}
}
